package com.abel.rabbitmq.mq;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Author: Abel.lin
 * Date: Created in 2018/5/31 16:18
 * Company: Abel.Studio
 * Copyright: Copyright (c) 2017
 * Description:
 */
@Configuration
public class RabbitConfig {

    /**
     * #普通、工作队列模式
     * 生产者负责生产消息，将消息发送到队列中，消费者监听队列，队列有消息就进行消费。
     * 当有多个消费者时，消费者平均消费队列中的消息。
     */
    public static final String NORMAL_QUEUE = "normal_queue";
    @Bean
    public Queue normalQueue(){
        return new Queue(NORMAL_QUEUE);
    }


    /**
     * #发布/订阅模式
     * 不处理路由键。只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
     * 很像子网广播，每台子网内的主机都获得了一份复制的消息。fanout 类型交换机转发消息是最快的。
     */
    public static final String FANOUT_QUEUE1 = "fanout_queue1";
    public static final String FANOUT_QUEUE2 = "fanout_queue2";
    public static final String FANOUT_EXCHANGE = "fanout_exchange";
    @Bean
    public Queue fanoutQueue1(){
        return new Queue(FANOUT_QUEUE1);
    }
    @Bean
    public Queue fanoutQueue2(){
        return new Queue(FANOUT_QUEUE2);
    }
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange(FANOUT_EXCHANGE);
    }
    @Bean
    public Binding fanoutBinding1(){
        return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
    }
    @Bean
    public Binding fanoutBinding2(){
        return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
    }

    /**
     * #路由模式
     * 处理路由键。需要将一个队列绑定到交换机上，要求该消息与一个特定的路由键完全匹配。
     * 如果一个队列绑定到该交换机上要求路由键 “dog”，则只有被标记为 “dog” 的消息才被转发，
     * 不会转发 dog.puppy，也不会转发 dog.guard，只会转发dog。
     */
    public static final String ROUTING_QUEUE1 = "routing_queue1";
    public static final String ROUTING_QUEUE2 = "routing_queue2";
    public static final String ROUTING_EXCHANGE = "routing_exchange";
    @Bean
    public Queue routing1(){
        return new Queue(ROUTING_QUEUE1);
    }
    @Bean
    public Queue routing2(){
        return new Queue(ROUTING_QUEUE2);
    }
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange(ROUTING_EXCHANGE);
    }
    @Bean
    public Binding routingBinding1(){
        return BindingBuilder.bind(routing1()).to(directExchange()).with("routing1");
    }
    @Bean
    public Binding routingBinding2(){
        return BindingBuilder.bind(routing2()).to(directExchange()).with("routing2");
    }

    /**
     * #主题模式
     * 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号 “#” 匹配一个或多个词，
     * 符号“*”匹配一个词。因此“testTopic.#” 能够匹配到“testTopic.abc.def”，但是“testTopic.*” 只会匹配到 “testTopic.abc”
     */
    public static final String TOPIC_QUEUE1 = "topic_queue1";
    public static final String TOPIC_QUEUE2 = "topic_queue2";
    public static final String TOPIC_QUEUE3 = "topic_queue3";
    public static final String TOPIC_EXCHANGE = "topic_exchange";
    @Bean
    public Queue topic1(){
        return new Queue(TOPIC_QUEUE1);
    }
    @Bean
    public Queue topic2(){
        return new Queue(TOPIC_QUEUE2);
    }
    @Bean
    public Queue topic3(){
        return new Queue(TOPIC_QUEUE3);
    }

    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(TOPIC_EXCHANGE);
    }
    @Bean
    public Binding topicBinding1(){
        return BindingBuilder.bind(topic1()).to(topicExchange()).with("testTopic.abc");
    }
    @Bean
    public Binding topicBinding2(){
        return BindingBuilder.bind(topic2()).to(topicExchange()).with("testTopic.*");
    }
    @Bean
    public Binding topicBinding3(){
        return BindingBuilder.bind(topic3()).to(topicExchange()).with("testTopic.#");
    }

}
